#include <bits/stdc++.h>
using namespace std;

const int N = 1000005;
const int MAXN = 100005;
bool det[N];
int T,n,m,L,V,a[MAXN],x,d[MAXN],v[MAXN],p,s;

struct Tree{
    int l,r;
    bool de;
}tree[N*4];

struct CAR{
    int l,r;
}car[N];

void build(int p,int l,int r)
{
    tree[p].de = 0;
    tree[p].l = l;
    tree[p].r = r;
    if (l == r)
    {
        tree[p].de = det[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(p*2,l,mid);
    build(p*2+1,mid + 1,r);
    tree[p].de = (tree[p*2].de|tree[p*2+1].de);

}

bool query(int p,int l,int r)
{
    if (l <= tree[p].l && tree[p].r <= r)
    {
        return tree[p].de;
    }
    int mid = (tree[p].l + tree[p].r) >> 1;
    bool s = 0;
    if (l <= mid)
    {
        s |= query(p*2,l,r);
    }
    if (mid < r)
    {
        s |= query(p*2+1,l,r);
    }
    return s;
}

bool cmp(CAR x,CAR y)
{
    if (x.r == y.r)
        return x.l < y.l;
    return x.r < y.r;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    cin >> T;
    while(T--)
    {
        memset(det,0,sizeof(det));
        //memset(a,0,sizeof(a));memset(d,0,sizeof(d));memset(v,0,sizeof(v));
        //memset(car,0,sizeof(car));
        cin >> n >> m >> L >> V;
        int VV = V * V;
        int ans = 0;
        for (int i = 1;i <= n;i++)
        {
            cin >> d[i] >> v[i] >> a[i];
            //car[i].d = 0;
        }
        for (int i = 1;i <= m;i++)
        {
            cin >> x;
            det[x] = true;
        }
        build(1,1,L);
        int cnt = 1;
        for (int i = 1;i <= n;i++)
        {
            if (a[i] == 0 || (a[i] > 0 && v[i] > V))
            {
                if (v[i] <= V)
                    continue;
                car[cnt].l = d[i];car[cnt].r = L;
                if (query(1,car[cnt].l,car[cnt].r))
                {
                    ans++;
                    cnt++;
                }
                continue;
            }
            if (a[i] > 0)
            {
                s = ((VV - v[i]*v[i]) >> 1) / a[i] ;
                if (d[i] + s > L)
                    continue;
                car[cnt].l = d[i] + s;car[cnt].r = L;
                if (query(1,car[cnt].l,car[cnt].r))
                {
                    ans++;
                    cnt++;
                }
                continue;
            }
            if (a[i] < 0)
            {
                if (v[i] <= V)
                    continue;
                a[i] *= -1;
                s = ((v[i]*v[i] - VV) >> 1) / a[i];
                car[cnt].l = d[i];car[cnt].r = min(d[i] + s,L);
                if (query(1,car[cnt].l,car[cnt].r))
                {
                    ans++;
                    cnt++;
                }
                continue;
            }

        }

        sort(car + 1,car + ans + 1,cmp);
        int po = -1;int ans2 = 0;
        for (int i = 1;i <= ans;i++)
        {
            if (po >= car[i].l)
                continue;
            for (int j = car[i].r;j >= car[i].l;j--)
            {
                if (det[j])
                {
                    ans2++;
                    po = j;
                    break;
                }
            }

        }
        /*
        for (int i = 1;i <= ans;i++)
        {
            cout << i << " " << car[i].l << " " << car[i].r << endl;
        }

        if (m - ans2 == 66850)
        {
            for (int i = 1;i <= ans;i++)
            {
                cout << i << " " << car[i].l << " " << car[i].r << endl;
            }
        }*/
        cout << ans << " " << m - ans2 << endl;
    }
    return 0;
}



